package com.corn.core.base.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.context.annotation.Lazy;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
@Component
@Lazy(true)
public abstract class BaseDaoImpl<PK extends Serializable,T> extends
		HibernateDaoSupport implements IBaseDao<PK, T> {

	private Class<T> indexType;

	public BaseDaoImpl() {
		this.indexType =  ((Class)((java.lang.reflect.ParameterizedType)super.getClass()
			      .getGenericSuperclass()).getActualTypeArguments()[1]);
	}

	public BaseDaoImpl(Class<T> type) {
		this.indexType = type;
		
	}

	
	public Session getSession() {
		return this.getSessionFactory().getCurrentSession();
	}
	
	@Resource
	public void setMySessionFactory(SessionFactory paramSessionFactory) {
		setSessionFactory(paramSessionFactory);
	}

	public void save(T entity) throws Exception {
		this.getHibernateTemplate().save(entity);
	}

	public void saveOrUpdate(T entity) throws Exception {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	public void delete(PK k) throws Exception {
		Assert.notNull(k);
		T t=get(k);
		if(t==null){
			throw new Exception("non-existent entity ");
		}
		getHibernateTemplate().delete(t);
	}

	public void delete(PK[] ks) throws Exception {
		Assert.notNull(ks);
		Assert.notEmpty(ks);
		for (PK k : ks) {
			getHibernateTemplate().delete(get(k));
		}
	}

	public T get(PK k) throws Exception {
		return getHibernateTemplate().get(this.indexType, k);
	}

	public T load(PK k) throws Exception {
		return getHibernateTemplate().load(this.indexType, k);
	}

	public List<T> loadAll() throws Exception {
		return getHibernateTemplate().loadAll(this.indexType);
	}

	public void deleteEntity(T entity) throws Exception {
		Assert.notNull(entity);
		getHibernateTemplate().delete(entity);
	}

	public void deleteEntity(T[] entitys) throws Exception {
		Assert.notNull(entitys);
		Assert.notEmpty(entitys);
		getHibernateTemplate().deleteAll(Arrays.asList(entitys));
	}

	public void modify(T entity) throws Exception {
		getHibernateTemplate().update(entity);
	}
	
	
	public List<?> findByCriteria(DetachedCriteria criteria,int firstResult, int maxResults) throws Exception {
		return getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
	}
	
	public List<?> findByCriteria(DetachedCriteria criteria) throws Exception {
		return getHibernateTemplate().findByCriteria(criteria);
	}
	
	public int findByCriteriaCount(DetachedCriteria criteria) throws Exception {
		List<?> counts=getHibernateTemplate().findByCriteria(criteria);
		if(null!=counts&&counts.size()>0){
			Object object=counts.get(0);
			if(null!=object){
				return Integer.valueOf(object.toString());
			}
		}
		return 0;
	}
	
	
	
	public List<?> findByNamedParam(String hql,String paramName,Object value) throws Exception {
		return getHibernateTemplate().findByNamedParam(hql, paramName, value);
	}
	
	public int findByNamedParamCount(String hql,String paramName,Object value) throws Exception {
		List<?> counts=getHibernateTemplate().findByNamedParam(hql, paramName, value);
		if(null!=counts&&counts.size()>0){
			Object object=counts.get(0);
			if(null!=object){
				return Integer.valueOf(object.toString());
			}
		}
		return 0;
	}
	
	public List<?> findByNamedParam(String hql,String[] paramName,Object[] values) throws Exception {
		return getHibernateTemplate().findByNamedParam(hql, paramName, values);
	}
	
	public int findByNamedParamCount(String hql,String[] paramName,Object[] values) throws Exception {
		List<?> counts=getHibernateTemplate().findByNamedParam(hql, paramName, values);
		if(null!=counts&&counts.size()>0){
			Object object=counts.get(0);
			if(null!=object){
				return Integer.valueOf(object.toString());
			}
		}
		return 0;
	}
	
	
	public List<?> findByNamedQuery(String hql,Object[] values) throws Exception {
		return getHibernateTemplate().findByNamedQuery(hql, values);
	}
	public int findByNamedQueryCount(String hql,Object[] values) throws Exception {
		List<?> counts=getHibernateTemplate().findByNamedQuery(hql, values);
		if(null!=counts&&counts.size()>0){
			Object object=counts.get(0);
			if(null!=object){
				return Integer.valueOf(object.toString());
			}
		}
		return 0;
	}
	
	
	public int modifyBatch(String hql) throws Exception
	  {
	    return getHibernateTemplate().bulkUpdate(hql);
	  }

	  public int modifyBatch(String hql, Object[] values)
	    throws Exception
	  {
	    return getHibernateTemplate().bulkUpdate(hql, values);
	  }

	public Class<T> getIndexType() {
		return indexType;
	}

	public void setIndexType(Class<T> indexType) {
		this.indexType = indexType;
	}

}
